const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 部分热更新
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
// js压缩
const TerserWebpackPlugin = require("terser-webpack-plugin");
// css 压缩
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// css 文件分离
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//获取cross-env定义的环境变量
const isProduction = process.env.NODE_ENV === "production";

const getStyleLoaders = function (pre) {
  return [
    isProduction ? MiniCssExtractPlugin.loader : 'style-loader', "css-loader", {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: ["postcss-preset-env"]
        }
      }
    },
    pre
  ].filter(Boolean)
}

module.exports = {
  mode: isProduction ? "production" : "development",
  devtool: isProduction ? 'eval-cheap-module-source-map' : "cheap-module-source-map",
  entry: './src/index.jsx',
  output: {
    filename: 'js/[name].[contenthash:10].js',
    path: path.resolve(__dirname, 'dist'),
    clean: true
  },
  resolve: {
    extensions: ['.jsx', '...'],
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
  module: {
    // 对应的文件需要对应的加载器
    rules: [
      {
        test: /\.jsx?$/,
        include: path.resolve(__dirname, './src'),
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-react', '@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: getStyleLoaders()
      },
      {
        test: /\.less$/,
        use: getStyleLoaders('less-loader')
      }
    ]
  },
  optimization: {
    splitChunks: {
      chunks: "all", //代码分割
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          chunks: "all",
          priority: 10, // 优先级
          enforce: true,
        },
      },
    },
    runtimeChunk: {
      name: entrypoint => `runtime~${entrypoint.name}.js` //单独储存引用的chunk的打包地址，main.js不会随着其他模块的变化导致地址变化而打包变化
    },
    minimizer: isProduction,
    minimizer: [
      new TerserWebpackPlugin(),
      new CssMinimizerPlugin(),
      new MiniCssExtractPlugin()
    ]
  },
  plugins: [
    // 修改打包后的index.html
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, './public/index.html')
    }),
    new ReactRefreshWebpackPlugin()
  ],
  devServer: {
    host: "0.0.0.0",
    port: 8377,
    open: true,
    hot: true,
    historyApiFallback: true//解决前端路由刷新404的问题
  },
  performance: false,
  cache: { //可开启webpack5内置缓存
    type: 'filesystem',
    allowCollectingMemory: true
  }
}